home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
SciAn
/
src
/
ScianVisBalls.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
17KB
|
644 lines
/*ScianVisBalls.c
Sept 23, 1992
Eric Pepke
Balls visualization object in SciAn*/
#include "Scian.h"
#include "ScianTypes.h"
#include "ScianArrays.h"
#include "ScianWindows.h"
#include "ScianTextBoxes.h"
#include "ScianButtons.h"
#include "ScianTitleBoxes.h"
#include "ScianObjWindows.h"
#include "ScianIcons.h"
#include "ScianColors.h"
#include "ScianControls.h"
#include "ScianLists.h"
#include "ScianSliders.h"
#include "ScianIDs.h"
#include "ScianDatasets.h"
#include "ScianPictures.h"
#include "ScianDialogs.h"
#include "ScianErrors.h"
#include "ScianComplexControls.h"
#include "ScianMethods.h"
#include "ScianStyle.h"
#include "ScianVisObjects.h"
#include "ScianVisBalls.h"
#include "ScianDraw.h"
#include "ScianTemplates.h"
#include "ScianTemplateHelper.h"
#include "ScianSymbols.h"
ObjPtr visBalls; /*Class for ball cloud*/
/*Ball style flags*/
#define BS_JACKS 2
#define BS_CUBES 4
#define BS_OCTOHEDRA 8
#define BS_SPHERES 16
/*Just in case I screw up*/
#undef DEFORMOBJ
#undef DEFCONSTANT
#undef DEFOFFSET
#undef DEFFACTOR
#undef DEFORMSWITCH
#define visDeformed HAHAHAHA
static ObjPtr AddBallsControls(object, panelContents)
ObjPtr object, panelContents;
/*Adds controls to a balls object*/
{
ObjPtr titleBox, checkBox;
ObjPtr var;
int style;
/*Get the style variable*/
var = GetIntVar("AddBallsControls", object, POINTSTYLE);
if (!var)
{
var = NewInt(BS_OCTOHEDRA);
SetVar(object, POINTSTYLE, var);
style = GetInt(var);
}
/*Make the title box*/
titleBox = TemplateTitleBox(BallsTemplate, "Style");
PrefixList(panelContents, titleBox);
SetVar(titleBox, PARENT, panelContents);
/*Make the check boxes*/
checkBox = TemplateCheckBox(BallsTemplate, "Jacks", style & BS_JACKS ? 1 : 0);
PrefixList(panelContents, checkBox);
SetVar(checkBox, PARENT, panelContents);
AssocFlagControlWithVar(checkBox, object, POINTSTYLE, BS_JACKS);
SetVar(checkBox, HELPSTRING,
NewString("When this box is on, jacks are drawn at all the nodes \
in the visualization. The size of the jacks can be controlled from within \
the Size control panel."));
checkBox = TemplateCheckBox(BallsTemplate, "Cubes", style & BS_CUBES ? 1 : 0);
PrefixList(panelContents, checkBox);
SetVar(checkBox, PARENT, panelContents);
AssocFlagControlWithVar(checkBox, object, POINTSTYLE, BS_CUBES);
SetVar(checkBox, HELPSTRING,
NewString("When this box is on, cubes are drawn at all the nodes \
in the visualization. The size of the cubes can be controlled from within \
the Size control panel."));
checkBox = TemplateCheckBox(BallsTemplate, "Octohedra", style & BS_OCTOHEDRA ? 1 : 0);
PrefixList(panelContents, checkBox);
SetVar(checkBox, PARENT, panelContents);
AssocFlagControlWithVar(checkBox, object, POINTSTYLE, BS_OCTOHEDRA);
SetVar(checkBox, HELPSTRING,
NewString("When this box is on, octohedra are drawn at all the nodes \
in the visualization. The size of the octohedra can be controlled from within \
the Size control panel."));
checkBox = TemplateCheckBox(BallsTemplate, "Spheres", style & BS_SPHERES ? 1 : 0);
PrefixList(panelContents, checkBox);
SetVar(checkBox, PARENT, panelContents);
AssocFlagControlWithVar(checkBox, object, POINTSTYLE, BS_SPHERES);
SetVar(checkBox, HELPSTRING,
NewString("When this box is on, spheres are drawn at all the nodes \
in the visualization. The size of the spheres can be controlled from within \
the Size control panel. The resolution of the spheres can be controlled from \
within the Geometry control panel."));
return ObjTrue;
}
typedef VertexPtr SixVertices[6];
typedef VertexPtr CubeVertices[2][2][2];
static ObjPtr MakeBallsSurface(balls)
ObjPtr balls;
/*Makes the surface of a balls object*/
{
ObjPtr ballsData;
ObjPtr surface;
ObjPtr var;
int style; /*Style of balls to make*/
var = GetVar(balls, POINTSTYLE);
if (var)
{
style = GetInt(var);
}
else
{
style = BS_OCTOHEDRA;
}
surface = NewPicture();
/*Get the main dataset*/
MakeVar(balls, MAINDATASET);
ballsData = GetVar(balls, MAINDATASET);
if (ballsData && style)
{
/*There is some data. Put stuff on the surface*/
int nTraversalDims; /*Number of dimensions to traverse*/
int whichDim; /*Dimension counter*/
long *traversalDims = 0; /*Dimensions of the dataset to traverse*/
long *index = 0; /*Counting index*/
long nNodes; /*# Total nodes in the dataset*/
VertexPtr *centerVertices = 0; /*Center vertices*/
SixVertices *faceVertices = 0; /*Face-centered vertices*/
CubeVertices *cornerVertices = 0; /*Corner vertices*/
long nVertices; /*Number of vertices so far*/
int nComponents; /*# components of data form*/
real size = 1.0; /*Size of the object*/
VertexPtr tv; /*Temporary vertex*/
long k; /*Counter*/
real x, y, z;
PicItemPtr item;
int sphereSub; /*# subdivisions in field*/
ObjPtr sizeObj; /*Object to size by*/
real offset, factor; /*Offset and factor for deformation*/
Bool sameForm; /*True iff forms are the same*/
var = GetIntVar("MakeBallsSurface", balls, SPHERESUBDIV);
if (var)
{
sphereSub = GetInt(var);
}
else
{
sphereSub = 2;
}
/*See if we need to size by an object*/
size = 1.0;
sizeObj = NULLOBJ;
if (style & (BS_JACKS | BS_CUBES | BS_OCTOHEDRA | BS_SPHERES))
{
if (GetPredicate(balls, SIZESWITCH))
{
MakeVar(balls, SIZEOBJ);
sizeObj = GetVar(balls, SIZEOBJ);
}
}
MakeVar(balls, SIZEFACTOR);
var = GetRealVar("MakeBallsSurface", balls, SIZEFACTOR);
if (var)
{
factor = GetReal(var);
}
else
{
factor = 1.0;
}
MakeVar(balls, SIZEOFFSET);
var = GetRealVar("MakeBallsSurface", balls, SIZEOFFSET);
if (var)
{
offset = GetReal(var);
}
else
{
offset = 0.0;
}
SetCurForm(FORMFIELD, ballsData);
nComponents = GetNComponents(FORMFIELD);
if (sizeObj)
{
SetCurField(FIELD1, sizeObj);
SetCurForm(FIELD2, sizeObj);
if (IdenticalFields(FORMFIELD, FIELD2))
{
sameForm = true;
}
else
{
sameForm = false;
}
}
else
{
MakeVar(balls, SIZECONSTANT);
var = GetRealVar("MakeBallsSurface", balls, SIZECONSTANT);
if (var)
{
size = GetReal(var) * factor + offset;
}
else
{
size = factor + offset;
}
}
/*Get the information on traversing the dataset*/
nTraversalDims = CountTraversalDims(FORMFIELD);
if (nTraversalDims)
{
traversalDims = (long *) Alloc(sizeof(long) * nTraversalDims);
index = (long *) Alloc(sizeof(long) * nTraversalDims);
}
else
{
index = (long *) Alloc(sizeof(long));
}
GetTraversalDims(FORMFIELD, traversalDims);
/*Calculate the number of nodes*/
nNodes = 1;
for (whichDim = 0; whichDim < nTraversalDims; ++whichDim)
{
if (traversalDims[whichDim] > 0)
{
nNodes *= traversalDims[whichDim];
}
}
/*Make as many vertices as we might need nodes*/
centerVertices = (VertexPtr *) Alloc(sizeof(VertexPtr) * nNodes);
if (!centerVertices)
{
OMErr();
return ObjFalse;
}
if ((style & BS_JACKS) || (style & BS_OCTOHEDRA))
{
faceVertices = (SixVertices *) Alloc(sizeof(SixVertices) * nNodes);
if (!faceVertices)
{
OMErr();
SAFEFREE(centerVertices);
return ObjFalse;
}
}
if ((style & BS_CUBES))
{
cornerVertices = (CubeVertices *) Alloc(sizeof(CubeVertices) * nNodes);
if (!cornerVertices)
{
OMErr();
SAFEFREE(centerVertices);
SAFEFREE(cornerVertices);
return ObjFalse;
}
}
/*Fill the vertices*/
nVertices = 0;
/*Zero the index*/
for (whichDim = 0; whichDim < nTraversalDims; ++whichDim)
{
index[whichDim] = 0;
}
/*Traverse all the balls*/
do
{
/*Sample the location at a ball*/
x = (0 >= nComponents) ? 0.0 : SelectFieldComponent(FORMFIELD, 0, index);
y = (1 >= nComponents) ? 0.0 : SelectFieldComponent(FORMFIELD, 1, index);
z = (2 >= nComponents) ? 0.0 : SelectFieldComponent(FORMFIELD, 2, index);
if (x == missingData) x = 0.0;
if (y == missingData) y = 0.0;
if (z == missingData) z = 0.0;
/*If there's a size object, make a new size*/
if (sizeObj)
{
if (sameForm)
{
size = SelectFieldScalar(FIELD1, index) * factor + offset;
}
else
{
real sample;
real position[3];
position[0] = x; position[1] = y; position[2] = z;
sample = SampleSpatScalar(FIELD1, FIELD2,
3, position, true);
size = sample * factor + offset;
}
}
/*Make a vertex*/
if (nVertices)
{
centerVertices[nVertices] = NewVertex(surface, VF_NEXTCANON);
}
else
{
centerVertices[nVertices] = NewVertex(surface, VF_FIRSTCANON);
}
/*Make some center vertices*/
centerVertices[nVertices] -> position[0] = x;
centerVertices[nVertices] -> position[1] = y;
centerVertices[nVertices] -> position[2] = z;
centerVertices[nVertices] -> normal[0] = 0.0;
centerVertices[nVertices] -> normal[0] = 0.0;
centerVertices[nVertices] -> normal[0] = 1.0;
centerVertices[nVertices] -> colorIndex = 2;
/*Put in the sphere if need be*/
if ((style & BS_SPHERES))
{
ConvertSphereOntoPicture(surface, centerVertices[nVertices], size,
VF_SAMEPLACE, sphereSub);
}
if ((style & BS_JACKS) || (style & BS_OCTOHEDRA))
{
/*Make some face centered vertices*/
faceVertices[nVertices][0] = tv = NewVertex(surface, VF_SAMEPLACE);
tv -> position[0] = x - size;
tv -> position[1] = y;
tv -> position[2] = z;
tv -> normal[0] = -1.0;
tv -> normal[1] = 0.0;
tv -> normal[2] = 0.0;
faceVertices[nVertices][1] = tv = NewVertex(surface, VF_SAMEPLACE);
tv -> position[0] = x + size;
tv -> position[1] = y;
tv -> position[2] = z;
tv -> normal[0] = 1.0;
tv -> normal[1] = 0.0;
tv -> normal[2] = 0.0;
faceVertices[nVertices][2] = tv = NewVertex(surface, VF_SAMEPLACE);
tv -> position[0] = x;
tv -> position[1] = y - size;
tv -> position[2] = z;
tv -> normal[0] = 0.0;
tv -> normal[1] = -1.0;
tv -> normal[2] = 0.0;
faceVertices[nVertices][3] = tv = NewVertex(surface, VF_SAMEPLACE);
tv -> position[0] = x;
tv -> position[1] = y + size;
tv -> position[2] = z;
tv -> normal[0] = 0.0;
tv -> normal[1] = 1.0;
tv -> normal[2] = 0.0;
faceVertices[nVertices][4] = tv = NewVertex(surface, VF_SAMEPLACE);
tv -> position[0] = x;
tv -> position[1] = y;
tv -> position[2] = z - size;
tv -> normal[0] = 0.0;
tv -> normal[1] = 0.0;
tv -> normal[2] = -1.0;
faceVertices[nVertices][5] = tv = NewVertex(surface, VF_SAMEPLACE);
tv -> position[0] = x;
tv -> position[1] = y;
tv -> position[2] = z + size;
tv -> normal[0] = 0.0;
tv -> normal[1] = 0.0;
tv -> normal[2] = 1.0;
}
#undef MAKECORNERVERTEX
#define MAKECORNERVERTEX(a, b, c) \
cornerVertices[nVertices][a][b][c] = tv = \
NewVertex(surface, VF_SAMEPLACE); \
tv -> position[0] = a ? x + size : x - size; \
tv -> position[1] = b ? y + size : y - size; \
tv -> position[2] = c ? z + size : z - size; \
tv -> normal[0] = a ? SQ33 : -SQ33; \
tv -> normal[1] = b ? SQ33 : -SQ33; \
tv -> normal[2] = c ? SQ33 : -SQ33;
if ((style & BS_CUBES))
{
/*Make some corner vertices*/
MAKECORNERVERTEX(0, 0, 0);
MAKECORNERVERTEX(0, 0, 1);
MAKECORNERVERTEX(0, 1, 0);
MAKECORNERVERTEX(0, 1, 1);
MAKECORNERVERTEX(1, 0, 0);
MAKECORNERVERTEX(1, 0, 1);
MAKECORNERVERTEX(1, 1, 0);
MAKECORNERVERTEX(1, 1, 1);
}
#undef MAKECORNERVERTEX
++nVertices;
/*Advance to next ball*/
for (whichDim = 0; whichDim < nTraversalDims; ++whichDim)
{
if (traversalDims[whichDim] > 0)
{
if ((++index[whichDim]) >= traversalDims[whichDim])
{
index[whichDim] = 0;
}
else
{
break;
}
}
}
} while (whichDim < nTraversalDims); /*Break is based on advance*/
if (style & BS_JACKS)
{
/*Make a jack*/
/*DIKEO do something about line width*/
for (k = 0; k < nVertices; ++k)
{
AppendSPolylineToPicture(surface, 1, 0, 2, &(faceVertices[k][0]));
AppendSPolylineToPicture(surface, 1, 0, 2, &(faceVertices[k][2]));
AppendSPolylineToPicture(surface, 1, 0, 2, &(faceVertices[k][4]));
}
}
#undef MAKETRI
#define MAKETRI(a, b, c) \
v[0] = faceVertices[k][a]; \
v[1] = faceVertices[k][b]; \
v[2] = faceVertices[k][c]; \
AppendSPolyToPolys(polys, 3, v);
if (style & BS_OCTOHEDRA)
{
/*Make some octohedra*/
PolysPtr polys;
VertexPtr v[3]; /*Vertices of triangles*/
for (k = 0; k < nVertices; ++k)
{
polys = AppendPolysToPicture(surface);
polys -> enclosed = true;
MAKETRI(0, 5, 3);
MAKETRI(3, 5, 1);
MAKETRI(1, 5, 2);
MAKETRI(2, 5, 0);
MAKETRI(0, 4, 2);
MAKETRI(2, 4, 1);
MAKETRI(1, 4, 3);
MAKETRI(3, 4, 0);
}
}
#undef MAKETRI
if (style & BS_CUBES)
{
/*Make some cubes*/
PolysPtr polys;
VertexPtr v[4]; /*Vertices of triangles*/
for (k = 0; k < nVertices; ++k)
{
polys = AppendPolysToPicture(surface);
/*DIKEO not quite right*/
v[0] = cornerVertices[k][0][0][0];
v[1] = cornerVertices[k][1][0][0];
v[2] = cornerVertices[k][1][1][0];
v[3] = cornerVertices[k][0][1][0];
AppendSPolyToPolys(polys, 4, v);
v[0] = cornerVertices[k][0][0][1];
v[1] = cornerVertices[k][0][1][1];
v[2] = cornerVertices[k][1][1][1];
v[3] = cornerVertices[k][1][0][1];
AppendSPolyToPolys(polys, 4, v);
v[0] = cornerVertices[k][0][0][0];
v[1] = cornerVertices[k][0][0][1];
v[2] = cornerVertices[k][1][0][1];
v[3] = cornerVertices[k][1][0][0];
AppendSPolyToPolys(polys, 4, v);
v[0] = cornerVertices[k][0][1][0];
v[1] = cornerVertices[k][1][1][0];
v[2] = cornerVertices[k][1][1][1];
v[3] = cornerVertices[k][0][1][1];
AppendSPolyToPolys(polys, 4, v);
v[0] = cornerVertices[k][0][0][0];
v[1] = cornerVertices[k][0][0][1];
v[2] = cornerVertices[k][0][1][1];
v[3] = cornerVertices[k][0][1][0];
AppendSPolyToPolys(polys, 4, v);
v[0] = cornerVertices[k][1][0][0];
v[1] = cornerVertices[k][1][1][0];
v[2] = cornerVertices[k][1][1][1];
v[3] = cornerVertices[k][1][0][1];
AppendSPolyToPolys(polys, 4, v);
}
}
SetVar(surface, MAINDATASET, ballsData);
/*Free up temporary storage*/
SAFEFREE(traversalDims);
SAFEFREE(index);
SAFEFREE(centerVertices);
SAFEFREE(faceVertices);
SAFEFREE(cornerVertices);
}
SetVar(balls, SURFACE, surface);
SetVar(surface, REPOBJ, balls);
return ObjTrue;
}
static ObjPtr BallsInit(balls)
ObjPtr balls;
/*Initializes a balls object*/
{
ObjPtr colorObj;
ObjPtr ballsField;
ObjPtr sizeObj;
MakeVar(balls, MAINDATASET);
SetVar(balls, COLOROBJ, colorObj = GetVar(balls, MAINDATASET));
if (colorObj)
{
ObjPtr mainDataset;
SetVar(balls, COLORS, ObjTrue);
/*See if there is a size object*/
while (mainDataset = GetVar(colorObj, MAINDATASET))
{
colorObj = mainDataset;
}
sizeObj = GetVar(colorObj, SIZEOBJ);
if (sizeObj)
{
SetVar(balls, SIZEOBJ, sizeObj);
SetVar(balls, SIZESWITCH, NewInt(1));
}
}
return ObjTrue;
}
static ObjPtr SetBallsMainDataset(visObj, dataSet)
ObjPtr visObj, dataSet;
/*Sets the main data set of visObj to dataSet*/
{
SetVar(visObj, MAINDATASET, dataSet);
return ObjTrue;
}
void InitBalls()
/*Initializes balls visualization object*/
{
ObjPtr icon;
/*Class for a ball cloud*/
visBalls = NewObject(visSized, 0);
AddToReferenceList(visBalls);
SetVar(visBalls, NAME, NewString("Balls"));
SetVar(visBalls, POINTSTYLE, NewInt(BS_OCTOHEDRA));
SetMethod(visBalls, INITIALIZE, BallsInit);
SetVar(visBalls, SIZEOFFSET, NewReal(0.0));
SetVar(visBalls, SIZEFACTOR, NewReal(1.0));
SetVar(visBalls, SIZECONSTANT, NewReal(1.0));
SetVar(visBalls, DEFAULTICON, icon = NewObject(visIcon, 0));
SetVar(icon, WHICHICON, NewInt(ICONBALLS));
SetVar(icon, NAME, NewString("Balls"));
SetVar(icon, HELPSTRING,
NewString("This icon represents a ball cloud or ball display object. \
This object can show a ball cloud or group of balls for just about any data field."));
DeclareIndirectDependency(visBalls, SURFACE, MAINDATASET, DATA);
DeclareIndirectDependency(visBalls, SURFACE, MAINDATASET, CHANGED);
DeclareIndirectDependency(visBalls, SURFACE, MAINDATASET);
DeclareDependency(visBalls, SURFACE, POINTSTYLE);
SetMethod(visBalls, SURFACE, MakeBallsSurface);
SetMethod(visBalls, SETMAINDATASET, SetBallsMainDataset);
SetVar(visBalls, STYLE, NewInt(0));
SetMethod(visBalls, ADDCONTROLS, AddBallsControls);
icon = NewIcon(0, 0, ICONBALLS, "Balls");
SetVar(icon, HELPSTRING,
NewString("Click on this icon to see a panel of controls for the ball object."));
SetVar(visBalls, CONTROLICON, icon);
DefineVisMapping(DS_HASFORM | DS_HASFIELD | DS_VECTOR, -1, -1, -1, visBalls);
DefineVisMapping(DS_HASFORM | DS_HASFIELD, -1, -1, -1, visBalls);
DefineVisMapping(DS_HASFORM | DS_HASFIELD | DS_VECTOR | DS_UNSTRUCTURED, -1, -1, -1, visBalls);
DefineVisMapping(DS_HASFORM | DS_HASFIELD | DS_UNSTRUCTURED, -1, -1, -1, visBalls);
}
void KillBalls()
/*Kills balls visualization*/
{
DeleteThing(visBalls);
}